home *** CD-ROM | disk | FTP | other *** search
/ Software of the Month Club 2000 October / Software of the Month - Ultimate Collection Shareware 277.iso / pc / PROGRAMS / UTILITY / WINLINUX / DATA1.CAB / programs_-_include / ASM-PPC / SEMAPHOR.{2V < prev    next >
Text File  |  1999-09-17  |  3KB  |  108 lines

  1. #ifndef _PPC_SEMAPHORE_HELPER_H
  2. #define _PPC_SEMAPHORE_HELPER_H
  3.  
  4. /*
  5.  * SMP- and interrupt-safe semaphores..
  6.  *
  7.  * (C) Copyright 1996 Linus Torvalds
  8.  * Adapted for PowerPC by Gary Thomas and Paul Mackerras
  9.  */
  10.  
  11. #include <asm/atomic.h>
  12.  
  13. /*
  14.  * These two (wake_one_more and waking_non_zero) _must_ execute
  15.  * atomically wrt each other.
  16.  *
  17.  * This is trivially done with load with reservation and
  18.  * store conditional on the ppc.
  19.  */
  20.  
  21. static inline void wake_one_more(struct semaphore * sem)
  22. {
  23.     atomic_inc(&sem->waking);
  24. }
  25.  
  26. static inline int waking_non_zero(struct semaphore *sem)
  27. {
  28.     int ret, tmp;
  29.  
  30.     /* Atomic decrement sem->waking iff it is > 0 */
  31.     __asm__ __volatile__(
  32.         "1:    lwarx %1,0,%2\n"    /* tmp = sem->waking */
  33.         "    cmpwi 0,%1,0\n"        /* test tmp */
  34.         "    addic %1,%1,-1\n"    /* --tmp */
  35.         "    ble- 2f\n"        /* exit if tmp was <= 0 */
  36.         "    stwcx. %1,0,%2\n"    /* update sem->waking */
  37.         "    bne- 1b\n"        /* try again if update failed*/
  38.         "    li %0,1\n"        /* ret = 1 */
  39.         "2:"
  40.         : "=r" (ret), "=&r" (tmp)
  41.         : "r" (&sem->waking), "0" (0)
  42.         : "cr0", "memory");
  43.  
  44.     return ret;
  45. }
  46. /*
  47.  * waking_non_zero_interruptible:
  48.  *    1    got the lock
  49.  *    0    go to sleep
  50.  *    -EINTR    interrupted
  51.  */
  52. static inline int waking_non_zero_interruptible(struct semaphore *sem,
  53.                         struct task_struct *tsk)
  54. {
  55.     int ret, tmp;
  56.  
  57.     /* Atomic decrement sem->waking iff it is > 0 */
  58.     __asm__ __volatile__(
  59.         "1:    lwarx %1,0,%2\n"    /* tmp = sem->waking */
  60.         "    cmpwi 0,%1,0\n"        /* test tmp */
  61.         "    addic %1,%1,-1\n"    /* --tmp */
  62.         "    ble- 2f\n"        /* exit if tmp was <= 0 */
  63.         "    stwcx. %1,0,%2\n"    /* update sem->waking */
  64.         "    bne- 1b\n"        /* try again if update failed*/
  65.         "    li %0,1\n"        /* ret = 1 */
  66.         "2:"
  67.         : "=r" (ret), "=&r" (tmp)
  68.         : "r" (&sem->waking), "0" (0)
  69.         : "cr0", "memory");
  70.  
  71.     if (ret == 0 && signal_pending(tsk)) {
  72.         atomic_inc(&sem->count);
  73.         ret = -EINTR;
  74.     }
  75.     return ret;
  76. }
  77.  
  78. /*
  79.  * waking_non_zero_trylock:
  80.  *    1    failed to lock
  81.  *    0    got the lock
  82.  */
  83. static inline int waking_non_zero_trylock(struct semaphore *sem)
  84. {
  85.     int ret, tmp;
  86.  
  87.     /* Atomic decrement sem->waking iff it is > 0 */
  88.     __asm__ __volatile__(
  89.         "1:    lwarx %1,0,%2\n"    /* tmp = sem->waking */
  90.         "    cmpwi 0,%1,0\n"        /* test tmp */
  91.         "    addic %1,%1,-1\n"    /* --tmp */
  92.         "    ble- 2f\n"        /* exit if tmp was <= 0 */
  93.         "    stwcx. %1,0,%2\n"    /* update sem->waking */
  94.         "    bne- 1b\n"        /* try again if update failed*/
  95.         "    li %0,0\n"        /* ret = 0 */
  96.         "2:"
  97.         : "=r" (ret), "=&r" (tmp)
  98.         : "r" (&sem->waking), "0" (1)
  99.         : "cr0", "memory");
  100.  
  101.     if (ret)
  102.         atomic_inc(&sem->count);
  103.  
  104.     return ret;
  105. }
  106.  
  107. #endif /* _PPC_SEMAPHORE_HELPER_H */
  108.